The present application relates generally to an improved data processing apparatus and method and more specifically to mechanisms for reconstructing a high level compilable program from an instruction trace.
A computer architecture simulator, or an architectural simulator, is a piece of software to model computer devices (or components) to predict outputs and performance metrics on a given input. An architectural simulator can model a target microprocessor only (see instruction set simulator), or an entire computer system (see full system simulator) including a processor, a memory system, and I/O devices.
A full-system simulator is an architecture simulator that simulates an electronic system at such a level of detail that complete software stacks from real systems can run on the simulator without any modification. A full system simulator effectively provides virtual hardware that is independent of the nature of the host computer. The full-system model typically has to include processor cores, peripheral devices, memories, interconnection buses, and network connections. The defining property of full-system simulation compared to an instruction set simulator is that the model allows real device drivers and operating systems to be run, not just single programs. Thus, full-system simulation makes it possible to simulate individual computers and networked computer nodes with all their software, from network device drivers to operating systems, network stacks, middleware, servers, and application programs.
A cycle-accurate simulator is a computer program that simulates a microarchitecture on a cycle-by-cycle basis. In contrast, an instruction set simulator simulates an instruction set architecture usually faster but not cycle-accurate to a specific implementation of the architecture. Instruction set simulators (ISS's) are often used when emulating older hardware where time precisions are very important for legacy reasons. More often cycle-accurate simulators (CAS) are used when designing new microprocessors as they can be tested and benchmarked accurately (including running full operating system, or compilers) without actually building a physical chip, and allow for easily changing the architecture design many times to meet an expected plan. Cycle-accurate simulators must ensure that all operations are executed in the proper virtual (or real if it is possible) time—branch prediction, cache misses, fetches, pipeline stalls, thread context switching, and many other subtle aspects of microprocessors.
Instruction Set Simulator (ISS) is a methodology employed for one of several possible reasons including: (1) to simulate the machine code of another hardware device or entire computer for upward compatibility (a full system simulator typically includes an instruction set simulator, e.g., the IBM 1401 was simulated on the later IBM/360 through use of microcode emulation); (2) to monitor and execute the machine code instructions (but treated as an input stream) on the same hardware for test and debugging purposes; and (3) to improve the speed performance, compared to a slower cycle accurate simulator, of simulations involving a processor core where the processor itself is not one of the elements being verified.
An ISS is often provided with (or is itself) a debugger in order for a software engineer/programmer to debug the program prior to obtaining target hardware. The basic instruction simulation technique is the same regardless of purpose. First the monitoring program is executed passing the name of the target program as an additional input parameter. The target program is then loaded into memory, but control is never passed to the code. Instead, the entry point within the loaded program is calculated, and a pseudo program status word (PSW) is set to this location. A set of pseudo registers are set to what they would have contained if the program had been given control directly. It may be necessary to amend some of these to point to other pseudo “control blocks” depending on the hardware and operating system. It may also be necessary to reset the original parameter list to “strip out” the previously added program name parameter. Thereafter, execution proceeds as follows:                1. Determine the length of the instruction at pseudo PSW location (initially the first instruction in the target program). If this instruction offset within the program matches a set of previously given “pause” points, set “Pause” reason, go to step 7 below;        2. “Fetch” the instruction from its original location (if necessary) into the monitor's memory. If “trace” is available and “on”, store program name, instruction offset and any other values;        3. Depending upon instruction type, perform pre-execution checks and execute. If the instruction cannot proceed for any reason (invalid instruction, incorrect mode etc.) go to step 7. If the instruction is about to alter memory, check memory destination exists (for this thread) and is sufficiently large. If OK, load appropriate pseudo registers into temporary real registers, perform equivalent move with the real registers, save address and length of altered storage if trace is “on” and go to step 4. If the instruction is a “register-to-register” operation, load pseudo registers into monitor's real registers, perform operation, store back to respective pseudo registers, go to step 4. If the instruction is a conditional branch, determine if the condition is satisfied: if not go to step 4, if condition is satisfied, calculate branch to address, determine if valid (if not, set error=“Wild branch”) and go to step 7. If OK, go to step 5. If instruction is an operating system call, do real call from monitoring program by “faking” addresses to return control to monitoring program and then reset pseudo registers to reflect call; go to step 4;        4. Add instruction length to current Pseudo PSW value;        5. Store next address in Pseudo PSW;        6. Go to step 1; and        7. Halt execution.        
For test and debugging purposes, the monitoring program can provide facilities to view and alter registers, memory, and restart location or obtain a mini core dump or print symbolic program names with current data values. It could permit new conditional “pause” locations, remove unwanted pauses, and the like.